/**
 * Licensed to the Rivulet under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     webapps/LICENSE-Rivulet-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.rivu.web.listener;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.rivues.core.RivuDataContext;
import com.rivues.module.platform.web.model.ConfigureParam;
import com.rivues.module.platform.web.model.SearchResultTemplet;
import com.rivues.module.platform.web.model.SystemLog;
import com.rivues.util.RivuTools;
import com.rivues.util.service.cache.CacheHelper;
import com.rivues.util.service.system.DataPersistenceService;
import com.rivues.util.tools.RuntimeData;

/**
 * @author jaddy0302 Rivulet WebApplicationContextListener.java 2010-3-3
 * 
 */
public class WebApplicationDataListener implements HttpSessionListener,
		ServletContextListener, ServletContextAttributeListener {
	private final Logger log = LoggerFactory.getLogger(WebApplicationDataListener.class); 
	/**
	* 
	*/
	@SuppressWarnings("unchecked")
	public void contextInitialized(ServletContextEvent sce) {
		RivuDataContext.setWac(WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()));
//		RivuDataContext.REAL_PATH = sce.getServletContext().getRealPath("/WEB-INF/");
		RivuDataContext.REAL_PATH = this.getClass().getResource("/").getPath().replaceAll("^\\/", "").replace("/classes/", "");
		RivuDataContext.setStart(true) ;
		RuntimeData runtimeData = new RuntimeData();	//初始化虚拟机 信息
		System.setProperty("java.util.logging.manager", "org.apache.logging.julbridge.JULBridgeLogManager") ;
		/**
		 * 首先判断是否存在 需要导入的 初始化文件，如果存在，则先导入，然后在处理
		 */
		try{
//			log.error("sce.getServletContext======================="+this.getClass().getResource("/").getPath());
//			log.error("sce.getServletContext.getResource======================="+sce.getServletContext().getResource("/").getPath());
			File file = new File(sce.getServletContext().getResource("/").getPath());
//			log.error("=======================file.exists==========================="+file.exists());
			if(file.exists()){
				for(File tmp :file.listFiles()){
//					log.error("t========================"+tmp.getName()+":"+tmp.getAbsolutePath());
				}
			}
		 } catch (MalformedURLException e){
			 e.printStackTrace();
		 }
		 
		File[] initFiles = new File(RivuDataContext.REAL_PATH , "data/initdata").listFiles() ;
		if(initFiles!=null && initFiles.length>0){
			log.info("获取初始化数据文件，文件个数："+initFiles.length+"，准备导入......");
		
			for(File initDataFile : initFiles){
				if(initDataFile.getName().endsWith(RivuDataContext.INIT_SCRIPT_FILE_EXT_NAME)){
					try {
						byte[] data = FileUtils.readFileToByteArray(initDataFile) ;
						if(data!=null && data.length > 0){
							List<?> initDataList = (List<?>) RivuTools.toObject(data) ;
							for(Object tempData : initDataList){
								List<?> existData = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(tempData.getClass()).add(Restrictions.eq("id", BeanUtils.getProperty(tempData, "id")))) ;
								if(existData.size()==0){
									RivuDataContext.getService().saveIObject(tempData);
								}
							}
						}
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}finally{
						/**
						 * 删除文件，避免多次启动导入
						 */
						initDataFile.delete() ;
					}
				}
			}
			if(initFiles.length>0){
				log.info("初始化数据文件导入成功，初始化数据文件已经移除。");
			}
		}
		/**
		 * 将 系统字典加入到缓存服务
		 */
		{
			List<ConfigureParam> configParamList = RivuDataContext.getService().findAllByCriteria(
					DetachedCriteria.forClass(ConfigureParam.class)) ;
			for(ConfigureParam param : configParamList){
				if (param.getName()!=null && param.getValue()!=null) {
					CacheHelper.getDistributedDictionaryCacheBean().put(param.getName(), param.getValue(), param.getOrgi()) ;
				}
			}
			List<SearchResultTemplet> templetList = RivuDataContext.getService().findAllByCriteria(
					DetachedCriteria.forClass(SearchResultTemplet.class)) ;
			
			for(SearchResultTemplet templet : templetList){
				CacheHelper.getDistributedDictionaryCacheBean().put(templet.getId(), templet, templet.getOrgi()) ;
			}
			RivuDataContext.initR3ContextData();
		}
	}

	public void sessionCreated(HttpSessionEvent arg0) {
		// TODO Auto-generated method stub
	}

	public void sessionDestroyed(HttpSessionEvent arg0) {
		
	}

	public void contextDestroyed(ServletContextEvent arg0) {
		SystemLog systemLog = new SystemLog() ;
		systemLog.setOrgi("SYSTEM");
		systemLog.setStartid(RivuDataContext.getSystemStartID()) ;
		systemLog.setStarttime(RivuDataContext.getStartTime()) ;
		systemLog.setEndtime(new Date());
		systemLog.setTimes((int)(systemLog.getEndtime().getTime()-systemLog.getStarttime().getTime())) ;
		if(RivuDataContext.isStart()){
			systemLog.setType(RivuDataContext.SystemLogType.STOP.toString());
			systemLog.setStatus("true") ;		//启动成功
		}else{
			systemLog.setType(RivuDataContext.SystemLogType.START.toString());
			systemLog.setStatus("false") ;		//启动失败
		}
		DataPersistenceService.persistence(systemLog) ;
		/**
		 * 以下线程等待两秒，等待 日志写入完毕
		 */
		try {
			Thread.sleep(2000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		} //
		//关闭集群
	}

	public void attributeAdded(ServletContextAttributeEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void attributeRemoved(ServletContextAttributeEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void attributeReplaced(ServletContextAttributeEvent arg0) {
		// TODO Auto-generated method stub

	}
}
